package com.cxb.service;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import android.app.AlertDialog;
import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Handler;
import android.os.Handler.Callback;
import android.os.IBinder;
import android.os.Message;
import android.os.StatFs;
import android.provider.VoicemailContract;
import android.text.TextUtils;
import android.util.Log;
import android.view.WindowManager;
import android.widget.Toast;

import com.cxb.R;
import com.cxb.manager.RootContext;
import com.cxb.utils.VolumnUtils;

/**
 * 监测内存和存储区
 * 
 * @author eric
 * 
 */
public class MemoryCleanUpService extends Service implements Callback {

	private static final int DEFAULT_DATA_THRESHOLD_BYTES = 20 * 1024 * 1024; // DATA区剩余空间阀值
	private static final int DEFAULT_SDCARD_EXTERNAL_THRESHOLD_BYTES = 70 * 1024 * 1024; // 外置sd卡阀值
	private static final int DEFAULT_SDCARD_INNER_THRESHOLD_BYTES = 50 * 1024 * 1024; // 内置sd卡阀值

	private static final int CHECK_MEMORY_PERIOD = 60 * 1 * 1000; // 检查内存时间间隔

	private static final int MSG_CLEAR_LOCKED_VIDEO = 2;
	private static final int MSG_CLEAR_MAP_DATA = 3;
	private static final int MSG_FACTORY_RESET = 1;
	private static final int MSG_FORMAT_EXTERNAL_SDCARD = 4;
	private final static String TAG = "MemoryCleanUpService";

	/**
	 * 删除文件，除了 without指定路径(绝对路径)
	 * 
	 * @param without
	 */
	private static void clearFileWithout(String rootPath, String... without) {
		File rootFile = new File(rootPath);
		if (!rootFile.exists()) {
			return;
		}

		File[] subFiles = rootFile.listFiles();
		for (File file : subFiles) {
			String subFilePath = file.getAbsolutePath();
			boolean isNoDelete = false;
			if (without != null) {
				for (String withoutPath : without) {
					if (subFilePath.equals(new File(withoutPath)
							.getAbsolutePath())) {
						// 不删除
						isNoDelete = true;
						break;
					}
				}
				if (isNoDelete) {
					continue;
				}
			}

			if (file.isDirectory() && file.list() != null
					&& file.list().length > 0) {
				clearFileWithout(file.getAbsolutePath(), without);
			} else {
				file.delete();
			}

		}

		if (rootFile.isDirectory() && rootFile.list().length == 0) {
			rootFile.delete();
		}

	}

	/**
	 * 删除文件，除了 without指定路径(相对路径)
	 * 
	 * @param without
	 */
	private static void clearFileWithoutByRelativePath(String rootPath,
			String... without) {

		for (int i = 0; i < without.length; i++) {
			without[i] = rootPath + "/" + without[i];
		}
		clearFileWithout(rootPath, without);
	}

	public static long getAvailableMemorySize(String volumn) {

		StatFs stat = new StatFs(volumn);
		long blockSize = stat.getBlockSize();
		long blockCount = stat.getBlockCount();
		if (blockCount == 0) {
			// 磁盘加载失败
			return -1;
		}
		long availableBlocks = stat.getAvailableBlocks();
		return availableBlocks * blockSize;

	}

	private Handler mHandler;

	private Timer mTimer;

	private RootContext rootContext;

	private final String SDCARD_EXTERNAL_PATH = "/mnt/sdcard2";

	private final String SDCARD_INNER_PATH = "/mnt/sdcard";

	private TimerTask timerTask;

	private void chearAPPData(String... appPkgName) {
		for (String pkg : appPkgName) {
			Log.i(TAG, "chearAPPData " + appPkgName);
			if (checkApkExist(this, pkg)) {
				rootContext.runCommand("pm clear " + pkg);
			}
		}
	}

	public boolean checkApkExist(Context context, String packageName) {
		if (TextUtils.isEmpty(packageName))
			return false;
		try {
			ApplicationInfo info = context.getPackageManager()
					.getApplicationInfo(packageName,
							PackageManager.GET_UNINSTALLED_PACKAGES);
			return true;
		} catch (NameNotFoundException e) {
			return false;
		}
	}

	private void restartAndClearYunZhiSheng() {
		RootContext.runCommandForResult("am force-stop com.chemi.framework");
		RootContext
				.runCommandForResult("am force-stop com.unisound.unicar.gui");
		RootContext.runCommandForResult("pm clear com.chemi.framework");
		RootContext.runCommandForResult("pm clear com.unisound.unicar.gui");

		RootContext
				.runCommandForResult("am startservice -n com.unisound.unicar.gui/com.unisound.unicar.gui.ui.WindowService");

	}

	// 检查内存
	private void checkMemory() {

		Log.i(TAG, "checkMemory");
		// 检查应用内存

		if (isDataFull()) {
			// 清理data
			Log.i(TAG, "data 区已经满了... ");
			// 1.后台操作
			Log.i(TAG, "开始清理云知声 ");
			restartAndClearYunZhiSheng();
			if (isDataFull()) {
				// 清除app数据
				String[] backgroundClearAPP = new String[] {
						"com.zzx.factorytest", "com.autonavi.minimap",
						"com.iflytek.inputmethod", "com.iflytek.speechcloud" };

				chearAPPData(backgroundClearAPP);
			}
			// 清除缓存的gps信息,及mqtt缓存信息
			// /////////////////////////////////////////////////

			// 静默卸载不相关应用
			uninstallOtherApp();

			// 2.前台提示后操作
			if (isDataFull()) {
				// 内存依旧不足时，提示恢复出厂设置
				mHandler.sendEmptyMessage(MSG_FACTORY_RESET);

			}

		} else if (isSdcardInnerFull()) {
			// 检查内置存储
			cleanSdcardInner();
			if (isSdcardInnerFull()) {
				// 无效 清除地图数据
				mHandler.sendEmptyMessage(MSG_CLEAR_MAP_DATA);
			}
		} else if (isSdcardExtenalFull()) {
			// 检查外置存储
			cleanSdcardExternal();
			if (isSdcardExtenalFull()) {

				File lockedVideoDir = new File(SDCARD_EXTERNAL_PATH
						+ "/CarRecord/LockedFile");

				if (lockedVideoDir.exists() && lockedVideoDir.list() != null
						&& lockedVideoDir.list().length > 4) {
					mHandler.sendEmptyMessage(MSG_CLEAR_LOCKED_VIDEO);
				} else {
					mHandler.sendEmptyMessage(MSG_FORMAT_EXTERNAL_SDCARD);
				}
			}

		}
	}

	private void cleanSdcardExternal() {

		// 1.删除除行车记录仪文件夹外的其他文件
		clearFileWithoutByRelativePath(SDCARD_EXTERNAL_PATH, "CarRecord");

		// 2.删除行车记录仪的临时文件,保留最新的一个文件
		File normalVideoDir = new File(SDCARD_EXTERNAL_PATH
				+ "/CarRecord/NormalFile");
		if (normalVideoDir.exists()) {
			File[] normalVideos = normalVideoDir.listFiles();
			File lastFile = null;
			for (File videoFile : normalVideos) {
				if (lastFile == null) {
					lastFile = videoFile;
				} else {
					if (lastFile.lastModified() < videoFile.lastModified()) {
						lastFile = videoFile;
					}
				}
			}
			if (lastFile != null) {
				clearFileWithout(normalVideoDir.getAbsolutePath(),
						lastFile.getAbsolutePath());
			}
		}
	}

	private void cleanSdcardInner() {

		// 清除没用的地图数据
		clearFileWithoutByRelativePath(SDCARD_INNER_PATH, "autonavidata70",
				"Android");

		clearFileWithoutByRelativePath(SDCARD_INNER_PATH + "/autonavidata70",
				"data", "GNaviData", "navi");
	}

	private AlertDialog alertDialog;

	public void showWarnDialog(final int msg) {
		if (alertDialog == null) {
			alertDialog = new AlertDialog.Builder(getApplicationContext())
					.create();
			alertDialog.getWindow().setType(
					WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
		}
		String title = "";
		String message = "";
		if (msg == MSG_FACTORY_RESET) {
			// 清理前台应用
			title = getString(R.string.data_space_is_full);// "手机DATA存储空间已满";
			message = getString(R.string.if_do_factory_reset);// "是否恢复出厂设置?";

		} else if (msg == MSG_CLEAR_MAP_DATA) {
			title = getString(R.string.inner_sdcard_space_is_full);// "手机内置存储存储空间已满";
			message = getString(R.string.clear_map_data);// "请清理地图数据\n操作方法好下:\n打开地图-->设置-->地图管理";
		} else if (msg == MSG_CLEAR_LOCKED_VIDEO) {
			title = getString(R.string.external_sdcard_space_is_full);// "SD卡存储空间不足";
			message = getString(R.string.locked_file_to_much_if_clear);// "锁定文件较多,是否清理?";
		} else if (msg == MSG_FORMAT_EXTERNAL_SDCARD) {
			title = getString(R.string.external_sdcard_space_is_full);// "SD卡存储空间不足";
			message = getString(R.string.if_format_sdcard);// "是否格式化SD卡?";
		}
		alertDialog.setTitle(title);
		alertDialog.setMessage(message);
		alertDialog.setButton(AlertDialog.BUTTON_NEGATIVE,
				getString(R.string.no), new DialogInterface.OnClickListener() {

					@Override
					public void onClick(DialogInterface dialog, int which) {

						dialog.dismiss();
					}
				});
		alertDialog.setButton(AlertDialog.BUTTON_POSITIVE,
				getString(R.string.yes), new DialogInterface.OnClickListener() {

					@Override
					public void onClick(DialogInterface dialog, int which) {
						dialog.dismiss();

						if (msg == MSG_FACTORY_RESET) {
							sendBroadcast(new Intent(
									"android.intent.action.MASTER_CLEAR"));

						} else if (msg == MSG_CLEAR_MAP_DATA) {
							// 打开地图
							Intent intent1 = new Intent();
							intent1.setAction(Intent.ACTION_MAIN);
							intent1.addCategory(Intent.CATEGORY_LAUNCHER);

							intent1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
									| Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
							intent1.setClassName("com.autonavi.minimap",
									"com.autonavi.map.activity.SplashActivity");
							startActivity(intent1);

						} else if (msg == MSG_CLEAR_LOCKED_VIDEO) {

							Toast.makeText(MemoryCleanUpService.this,
									R.string.clearing, 0).show();
							clearFileWithout(SDCARD_EXTERNAL_PATH
									+ "/CarRecord/LockedFile", null);
							Toast.makeText(MemoryCleanUpService.this,
									R.string.clear_ok, 0).show();
						} else if (msg == MSG_FORMAT_EXTERNAL_SDCARD) {
							// Intent intent = new Intent();
							// intent.setComponent(new ComponentName("android",
							// "com.android.internal.os.storage.ExternalStorageFormatter"));
							// startService(intent);
							new VolumnUtils(MemoryCleanUpService.this)
									.formatVolumn(VolumnUtils.VOLUMN_EXTERNAL_SDCARD_PATH);
						}
					}
				});
		alertDialog.show();
	}

	@Override
	public boolean handleMessage(Message msg) {
		if (msg.what == MSG_FACTORY_RESET) {
			// 清理前台应用
			showWarnDialog(MSG_FACTORY_RESET);
		} else if (msg.what == MSG_CLEAR_MAP_DATA) {
			showWarnDialog(MSG_CLEAR_MAP_DATA);
		} else if (msg.what == MSG_CLEAR_LOCKED_VIDEO) {
			showWarnDialog(MSG_CLEAR_LOCKED_VIDEO);
		} else if (msg.what == MSG_FORMAT_EXTERNAL_SDCARD) {
			showWarnDialog(MSG_FORMAT_EXTERNAL_SDCARD);
		}
		return false;
	}

	private boolean isDataFull() {
		long dataSize = getAvailableMemorySize("/data");
		return dataSize >= 0 && dataSize < DEFAULT_DATA_THRESHOLD_BYTES;
	}

	private boolean isSdcardExtenalFull() {
		long dataSize = getAvailableMemorySize(SDCARD_EXTERNAL_PATH);
		return dataSize >= 0
				&& dataSize < DEFAULT_SDCARD_EXTERNAL_THRESHOLD_BYTES;
	}

	private boolean isSdcardInnerFull() {
		long dataSize = getAvailableMemorySize(SDCARD_INNER_PATH);
		return dataSize >= 0 && dataSize < DEFAULT_SDCARD_INNER_THRESHOLD_BYTES;
	}

	@Override
	public IBinder onBind(Intent intent) {

		return null;
	}

	@Override
	public void onCreate() {
		rootContext = RootContext.getInstance();
		mHandler = new Handler(this);
		mTimer = new Timer();
		timerTask = new TimerTask() {
			@Override
			public void run() {
				checkMemory();
			}
		};
		mTimer.schedule(timerTask, CHECK_MEMORY_PERIOD, CHECK_MEMORY_PERIOD);

		super.onCreate();
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {

		return super.onStartCommand(intent, flags, startId);
	}

	private boolean uninstallApp(String pkgName) {
		if (TextUtils.isEmpty(pkgName)) {
			return false;
		}
		Log.i(TAG, "uninstall " + pkgName);
		rootContext.runCommand("pm uninstall " + pkgName);

		return true;
	}

	private void uninstallOtherApp() {

		// 获取system_backup文件夹的出厂应用
		PackageManager packageManager = getPackageManager();
		List<String> systemBackupAppList = new ArrayList<String>();
		File[] backupApp = new File("/system/appbackup").listFiles();
		List<String> whiteList = new ArrayList<String>();
		whiteList.add("com.autonavi.xmgd.navigator");
		whiteList.add("com.iflytek.inputmethod");
		whiteList.add("com.autonavi.minimap");
		for (File apk : backupApp) {
			PackageInfo pkgInfo = packageManager.getPackageArchiveInfo(
					apk.getAbsolutePath(), PackageManager.GET_ACTIVITIES);
			if (pkgInfo != null) {

				systemBackupAppList.add(pkgInfo.packageName);
			}
		}

		// 取得安装的第三方应用
		List<ApplicationInfo> applicationList = packageManager
				.getInstalledApplications(0);
		for (ApplicationInfo app : applicationList) {
			if ((app.flags & ApplicationInfo.FLAG_SYSTEM) <= 0) {
				// 第三方应用，卸载
				if (!systemBackupAppList.contains(app.packageName)
						&& !this.getPackageName().equals(app.packageName)
						&& !whiteList.contains(app.packageName)) {
					uninstallApp(app.packageName);
				}
			}
		}

	}
}
